module controller.admin_ctrl;

import std.conv : to;
import std.stdio;
import std.array : appender;

import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
import vibe.data.json : Json, serializeToJson, deserializeJson;
import darktemple.render;

import model.article;
import model.category;
import service.user_service;
import service.article_service;
import service.cate_service;
import utils.const_val;
import utils.my_jwt;

/** 
 * 接收批量删除文章或分类的post id数据
 */
struct BatchDeletePostData
{
    // 文章id列表 或 分类id列表
    int[] ids;
}

/** 
 * 后台登录页
 */
void getAdminLoginPage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/login.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * 后台登录post
 */
void handleLoginPost (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    import std.digest.sha : sha256Of, Order, LetterCase;
    import std.digest : toHexString;
    import std.datetime.systime : Clock;
    import core.time : seconds;

    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json postData = req.json();
    if (postData.type == Json.Type.undefined || postData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    string username = postData["username"].get!string;
    string password = postData["password"].get!string;
    if (username is null || username == "" || password is null || password == "")
    {
        resData["msg"] = "用户名或密码不能为空";
        return res.writeJsonBody(resData, 400);
    }

    auto dbUser = getUserByUsername(username);
    if (dbUser.isNull)
    {
        resData["msg"] = "用户名或密码不正确";
        return res.writeJsonBody(resData, 400);
    }
    auto user = dbUser.get;

    string encodePwd = toHexString!(Order.increasing, LetterCase.lower)(
        sha256Of(password ~ SALT_STR));

    // writeln("加密后的密码: " ~ encodePwd);

    if (user.password != encodePwd)
    {
        resData["msg"] = "用户名或密码不正确";
        return res.writeJsonBody(resData, 400);
    }

    // 生成jwt token
    long exp = Clock.currTime.toUnixTime() + 7200; // 过期时间2小时
    Json userData = Json([
        "id" : Json(user.id),
        "username" : Json(user.username),
        "exp" : Json(exp),
    ]);
    string token = createToken(userData);
    Json resObj = Json([
        "id" : Json(user.id),
        "username" : Json(user.username),
        "nickname" : Json(user.nickname),
        "token" : Json(token),
    ]);

    resData["code"] = 200;
    resData["msg"] = "ok";
    resData["data"] = resObj;
    res.writeJsonBody(resData, 200);
}

/** 
 * 后台首页
 */
void getAdminIndexPage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/index.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * 后台菜单
 */
void getAdminMenu (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string menu = `
[
    {
        "id": 1,
        "title": "工作空间",
        "icon": "layui-icon layui-icon-console",
        "type": 0,
        "children": [
            {
                "id": "11",
                "title": "工作台",
                "icon": "layui-icon layui-icon-console",
                "type": 1,
                "openType": "_component",
                "href": "/admin/console1"
            }
        ]
    },
    {
        "id": 2,
        "title": "文章管理",
        "icon": "layui-icon layui-icon-auz",
        "type": 0,
        "children": [
            {
                "id": 21,
                "title": "写文章",
                "icon": "layui-icon layui-icon-face-smile",
                "type": 1,
                "openType": "_component",
                "href": "/admin/article/write"
            },
            {
                "id": 22,
                "title": "文章管理",
                "icon": "layui-icon layui-icon-face-smile",
                "type": 1,
                "openType": "_component",
                "href": "/admin/article/manage"
            }
        ]
    },
    {
        "id": 3,
        "title": "分类管理",
        "icon": "layui-icon layui-icon-auz",
        "type": 0,
        "children": [
            {
                "id": 31,
                "title": "分类管理",
                "icon": "layui-icon layui-icon-face-smile",
                "type": 1,
                "openType": "_component",
                "href": "/admin/category/manage"
            }
        ]
    }
]`;
    res.writeBody(menu, "application/json; charset=utf-8");
}

/** 
 * 后台控制台
 */
void getAdminConsolePage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/console.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * 写文章页面
 */
void getWriteArticlePage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/write_article.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * post提交发布文章
 */
void handlePublishArticlePost (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    ArticleDtoForCreate article;
    try
    {
        article = deserializeJson!ArticleDtoForCreate(jsonData);
    }
    catch (Exception e)
    {
        resData["msg"] = "参数错误";
        return res.writeJsonBody(resData, 400);
    }

    bool result = addArticle(article);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "添加文章失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData, 201);
}

/** 
 * 文章管理页面
 */
void getArticleManagePage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/article_manage.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * 文章管理页文章列表数据
 */
void getArticleManageList (scope HTTPServerRequest req, scope HTTPServerResponse res)
{

    string pageNumStr = req.query.get("page_num", "1");
    string pageSizeStr = req.query.get("page_size", "20");
    int pageNum = to!int(pageNumStr);
    int pageSize = to!int(pageSizeStr);

    auto articles = getArticleListByPaginate(pageNum, pageSize);
    int total = getArticleTotalCount();

    Json resData = Json.emptyObject;
    resData["code"] = 200;
    resData["msg"] = "ok";
    resData["total"] = total;
    resData["data"] = serializeToJson(articles);

    res.writeJsonBody(resData);
}

/** 
 * put提交更新文章
 */
void handleEditArticlePut (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    ArticleDtoForUpdate article;
    try
    {
        article = deserializeJson!ArticleDtoForUpdate(jsonData);
    }
    catch (Exception e)
    {
        resData["msg"] = "参数错误";
        return res.writeJsonBody(resData, 400);
    }

    bool result = updateArticle(article);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "更新文章失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * delete提交删除文章
 */
void handleArticleDelete (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    string id = req.params.get("id", "");
    if (id == "")
    {
        return res.writeJsonBody(resData, 400);
    }
    int articleId = to!int(id);

    bool result = deleteArticle(articleId);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "删除文章失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * post提交批量删除文章
 */
void handleArticleBatchDelete (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    auto postData = deserializeJson!BatchDeletePostData(jsonData);

    bool result = batchDeleteArticles(postData.ids);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "批量删除文章失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * 分类管理页面
 */
void getCategoryManagePage (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    string html = renderFile!("admin/category_manage.tmpl");
    res.writeBody(html, "text/html; charset=utf-8");
}

/** 
 * post提交添加分类
 */
void handleAddCategoryPost (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    CategoryDtoForCreate category;
    try
    {
        category = deserializeJson!CategoryDtoForCreate(jsonData);
    }
    catch (Exception e)
    {
        resData["msg"] = "参数错误";
        return res.writeJsonBody(resData, 400);
    }

    bool result = addCategory(category);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "添加分类失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * put提交编辑分类
 */
void handleEditCategoryPut (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    CategoryDtoForUpdate category;
    try
    {
        category = deserializeJson!CategoryDtoForUpdate(jsonData);
    }
    catch (Exception e)
    {
        resData["msg"] = "参数错误";
        return res.writeJsonBody(resData, 400);
    }

    bool result = updateCategory(category);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "编辑分类失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * delete提交删除分类
 */
void handleCategoryDelete (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    string id = req.params.get("id", "");
    if (id == "")
    {
        return res.writeJsonBody(resData, 400);
    }
    int cateId = to!int(id);

    bool result = deleteCategory(cateId);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "删除分类失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}

/** 
 * post提交批量删除分类
 */
void handleCategoryBatchDelete (scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    Json resData = Json.emptyObject;
    resData["code"] = 400;
    resData["msg"] = "错误的请求";
    resData["data"] = null;

    Json jsonData = req.json;
    if (jsonData.type == Json.Type.null_ || jsonData.type == Json.Type.undefined || jsonData.length == 0)
    {
        return res.writeJsonBody(resData, 400);
    }

    BatchDeletePostData postData;
    try
    {
        postData = deserializeJson!BatchDeletePostData(jsonData);
    }
    catch (Exception e)
    {
        resData["msg"] = "参数错误";
        return res.writeJsonBody(resData, 400);
    }

    bool result = batchDeleteCategory(postData.ids);
    if (!result)
    {
        resData["code"] = 500;
        resData["msg"] = "批量删除分类失败";
        return res.writeJsonBody(resData, 500);
    }

    resData["code"] = 200;
    resData["msg"] = "ok";
    res.writeJsonBody(resData);
}
